package com.randi.system.service;

import com.randi.common.constant.Constants;
import com.randi.common.utils.ServletUtils;
import com.randi.common.utils.StringUtils;
import com.randi.common.utils.ip.AddressUtils;
import com.randi.common.utils.ip.IpUtils;
import com.randi.system.domain.entity.sysLog.SysLogLogin;
import com.randi.system.service.sysLog.ISysLogLoginService;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author ziye
 */
@Component
@Slf4j
public class SysLogThreadService {

    private static final Logger logger = LoggerFactory.getLogger("com.randi.framework.service.SysLogThreadService");

    @Resource
    private ISysLogLoginService iSysLogLoginService;

    /**
     * 打印日志信息
     *
     * @param info loginInfo
     */
    private void formatMessage(SysLogLogin info) {
        logger.info("----------------------------------------------------------------------");
        String type = info.getType() != null && info.getType() == 1 ? "Logout" : "Login";
        logger.info(StringUtils.format("{} user name is [{}]", type, info.getUserName()));
        logger.info(StringUtils.format("Address {}", info.getIpAddress()));
        logger.info(StringUtils.format("Location {}", info.getLoginLocation()));
        logger.info(StringUtils.format("Browser {}", info.getBrowser()));
        logger.info(StringUtils.format("OS {}", info.getOs()));
        if (info.getStatus() == null || info.getStatus() == 0) {
            logger.info(info.getMessage());
        } else {
            logger.error(info.getMessage());
        }
        logger.info("----------------------------------------------------------------------");
    }

    /**
     * 设置登录日志信息
     *
     * @param loginInfo loginInfo
     */
    private void setLogLoginOtherInfo(SysLogLogin loginInfo) {
        HttpServletRequest request = ServletUtils.getRequest();
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));

        // 获取客户端操作系统
        String os = userAgent.getOperatingSystem().getName();
        // 获取客户端浏览器
        String browser = userAgent.getBrowser().getName();
        // 获取IP地址
        String ip = IpUtils.getIpAddress();
        // 获取地址
        String address = AddressUtils.getRealAddressByIP(ip);

        loginInfo.setIpAddress(ip);
        loginInfo.setLoginLocation(address);
        loginInfo.setBrowser(browser);
        loginInfo.setOs(os);
    }

    /**
     * 设置登录日志信息
     *
     * @param userName 用户名
     * @param status   status
     * @param message  message
     */
    public void handleLoginInfo(String userName, String status, String message) {
        // 封装对象
        SysLogLogin loginInfo = new SysLogLogin();
        loginInfo.setUserName(userName);
        loginInfo.setMessage(message);
        loginInfo.setLoginTime(new Date());
        loginInfo.setType(0);
        if (status.equals(Constants.LOGIN_OUT)) {
            loginInfo.setType(1);
        }
        // 日志状态
        if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGIN_OUT, Constants.REGISTER)) {
            loginInfo.setStatus(0);
        } else if (Constants.LOGIN_FAIL.equals(status)) {
            loginInfo.setStatus(1);
        }

        setLogLoginOtherInfo(loginInfo);
        this.handleLoginInfo(loginInfo);
    }

    /**
     * 插入登入日志
     *
     * @param loginInfo 用户名
     */
    @Async("TaskExecutor")
    public void handleLoginInfo(SysLogLogin loginInfo) {
        // 打印信息到日志
        formatMessage(loginInfo);
        iSysLogLoginService.insertSysLogLogin(loginInfo);
    }

}
